/*****************************************************************************
 * Copyright (C) Stacy Curl. All rights reserved.                            *
 * ------------------------------------------------------------------------- *
 * The software in this package is published under the terms of the BSD      *
 * style license a copy of which has been included with this distribution in *
 * the LICENSE.txt file.                                                     *
 *****************************************************************************/
package picounit.features.verify.constraint;

public class ComparesTo extends ModifiableConstraint<ComparesTo> {
	private final Comparitor comparitor;
	private final Object compareTo;

	public ComparesTo(Object compareTo, Modifier modifier, Comparitor comparitor) {
		super(modifier);

		this.compareTo = compareTo;
		this.comparitor = comparitor;
	}

	@Override
	@SuppressWarnings("unchecked")
	public boolean evaluate(Object value) {
		return comparitor.compare(modifyToComparable(value), modifyToComparable(compareTo));
	}

	@Override
	public String describeFailureImpl() {
		return "is not " + comparitor.description() + " <" + compareTo + ">";
	}

	///////////////////////////////////////////////////////////////////////////////////////////////
	// Equal methods
	///////////////////////////////////////////////////////////////////////////////////////////////

	@Override
	public boolean equalTo(ComparesTo comparesTo) {
		return compareTo.equals(comparesTo.compareTo) &&
			comparitor.equals(comparesTo.comparitor);
	}
	
	///////////////////////////////////////////////////////////////////////////////////////////////
	// Object methods
	///////////////////////////////////////////////////////////////////////////////////////////////
	
	@Override
	public int hashCode() {
		return compareTo.hashCode() ^ comparitor.description().hashCode();
	}

	@Override
	public String toString() {
		return "Is " + comparitor.description() + ": " + compareTo;
	}

	///////////////////////////////////////////////////////////////////////////////////////////////
	// Implementation methods
	///////////////////////////////////////////////////////////////////////////////////////////////

	private Comparable modifyToComparable(Object object) {
		return (Comparable) modify(object);
	}
}
